import { A } from '@ember/array';

import { module, test } from 'qunit';

import { setupTest } from 'ember-qunit';

import { FetchManager, SnapshotRecordArray } from '@ember-data/legacy-compat/-private';
import Model, { attr } from '@ember-data/model';

module('Unit - snapshot-record-array', function (hooks) {
  setupTest(hooks);

  test('constructor', function (assert) {
    const array = A([1, 2]);
    array.content = [1, 2];
    const options = {
      adapterOptions: 'some options',
      include: 'include me',
    };

    const snapshot = new SnapshotRecordArray(
      {
        peekAll() {
          return array;
        },
      },
      'user',
      options
    );

    assert.strictEqual(snapshot.length, 2);
    assert.strictEqual(snapshot.adapterOptions, 'some options');
    assert.strictEqual(snapshot.include, 'include me');
  });

  test('#snapshot', function (assert) {
    const { owner } = this;
    owner.register(
      'model:dog',
      class extends Model {
        @attr name;
      }
    );
    const store = owner.lookup('service:store');
    store._fetchManager = new FetchManager(store);

    store.push({
      data: {
        type: 'dog',
        id: '1',
        attributes: { name: 'Shen' },
      },
    });

    const options = {
      adapterOptions: 'some options',
      include: 'include me',
    };
    let didTakeSnapshot = 0;
    const snapshotsTaken = [];

    const create = store._fetchManager.createSnapshot;
    store._fetchManager.createSnapshot = function () {
      didTakeSnapshot++;
      const snapshot = create.apply(this, arguments);
      snapshotsTaken.push(snapshot);
      return snapshot;
    };
    const snapshot = new SnapshotRecordArray(store, 'dog', options);

    assert.strictEqual(didTakeSnapshot, 0, 'no shapshot should yet be taken');
    assert.strictEqual(snapshot.snapshots()[0], snapshotsTaken[0], 'should be correct snapshot');
    assert.strictEqual(didTakeSnapshot, 1, 'one snapshot should have been taken');
    assert.strictEqual(snapshot.snapshots()[0], snapshotsTaken[0], 'should return the exact same snapshot');
    assert.strictEqual(didTakeSnapshot, 1, 'still only one snapshot should have been taken');
  });
});
